package test.filter;

import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class FrontController extends HttpServlet {

	@Override
	protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		hadlerRequest(req, resp);
	}
	
	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		hadlerRequest(req, resp);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		hadlerRequest(req, resp);
	}
	
	@Override
	protected void doPut(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		hadlerRequest(req, resp);
	}
	
	private void hadlerRequest(HttpServletRequest req, HttpServletResponse resp) {
		try {
			Handler handler = handlerMapping(req);
			String viewName = handlerAdapter(handler, req, resp);
			dispatch(viewName, req, resp);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}

	private void dispatch(String viewName, HttpServletRequest req,
			HttpServletResponse resp) throws ServletException, IOException {
		String resultViewName = "/WEB-INF/views/" + viewName + ".jsp";
		RequestDispatcher dispatcher = req.getRequestDispatcher(resultViewName);
		dispatcher.forward(req, resp);
	}

	private String handlerAdapter(Handler handler, HttpServletRequest req, HttpServletResponse resp) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
		Method handlerMethod = handler.getClass().getMethod("handler", HttpServletRequest.class, HttpServletResponse.class);
		return (String) handlerMethod.invoke(handler, req, resp);
	}

	private Handler handlerMapping(HttpServletRequest req) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
		String uri = req.getRequestURI();
		String handlerName = "test.filter." + uri.substring(uri.lastIndexOf("/") + 1) + "Handler";
		Class handlerClass = Class.forName(handlerName);
		return (Handler) handlerClass.newInstance();
	}
	
}
